<template>
  <div class="detail">
    <div class="detail-title">
      {{ detailObj.title }}
    </div>
    <div class="detail-body">
      <div class="detail-body-img">
        <el-image
          class="img"
          :src="detailObj.cover"
          :preview-src-list="[detailObj.cover]"
        ></el-image>
        <span @click="dialogFormVisible = true">更改封面或信息</span>
      </div>
      <div class="detail-body-info">
        <span>作者: {{ detailObj.auhnor }}</span>
        <span>出版社: {{ detailObj.publishingHouse }} </span>
        <span>原作名: {{ detailObj.formerly }}</span>
        <span>出版年: {{ detailObj.year }}</span>
        <span>页数: {{ detailObj.pages }}</span>
        <span
          >定价: {{ detailObj.price ? detailObj.price.toFixed(2) : 0 }}元</span
        >
        <span>ISBN: {{ detailObj.isbn }}</span>
      </div>
      <div class="detail-body-rate">
        <div>平台评分</div>
        <div class="rate-data">
          <div class="rate-data-num">
            {{ rateObj.avgRate ? rateObj.avgRate.toFixed(1) : 0.0 }}
          </div>
          <div class="rate-data-star">
            <el-rate
              v-model="rateVal"
              style="font-size: 20px"
              disabled
              text-color="#ff9900"
            >
            </el-rate>
            <span>{{ rateObj.rateCount }}人评分</span>
          </div>
        </div>
        <div class="rate-ranking">
          <PercentageView :starList="starList"></PercentageView>
        </div>
      </div>
      <div class="detail-body-operate">
        <el-button
          class="operate-btn"
          :class="{ wantOrSee_f: want == 0, wantOrSee_t: want != 0 }"
          @click="wantOrSeeChange('want')"
          :loading="wantLoading"
          >{{ want == 0 ? "想读" : "已收藏" }}</el-button
        >
        <el-button
          class="operate-btn"
          :class="{ wantOrSee_f: see == 0, wantOrSee_t: see != 0 }"
          @click="wantOrSeeChange('see')"
          :loading="seeLoading"
          >{{ see == 0 ? "读过" : "已读过" }}</el-button
        >
        <div class="operate-rate">
          评分：<el-rate
            v-model="writeRateValue"
            show-text
            @change="rateChange"
          ></el-rate>
        </div>
        <span>
          <el-link type="info" @click="writeRemark"
            ><i class="el-icon-edit"></i>写短评</el-link
          >
        </span>
      </div>
    </div>
    <div class="detail-introduce">
      <div class="detail-introduce-title">{{ detailObj.title }}的内容简介</div>
      <div class="detail-introduce-content">
        <p>{{ detailObj.detail }}</p>
      </div>
    </div>
    <div class="detail-remark">
      <div class="remark-title">{{ detailObj.title }}的短评</div>
      <RemarkView :remarkList="remarkList"></RemarkView>
      <el-pagination
        v-show="remarkList.length > 0"
        layout="prev, pager, next"
        :current-page="currentPage"
        @current-change="handleCurrentChange"
        :total="total"
        :page-count="7"
        style="text-align: right; margin-top: 20px"
      >
      </el-pagination>
    </div>
    <!-- dialog框（修改信息） -->
    <el-dialog
      title="修改信息"
      :visible.sync="dialogFormVisible"
      @close="closeFormDialog"
      :close-on-click-modal="false"
    >
      <el-form :rules="rulesUpdate" ref="updateForm" :model="updateObj">
        <el-form-item label="书名" prop="title" :label-width="formLabelWidth">
          <el-input v-model="updateObj.title" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="作者" prop="auhnor" :label-width="formLabelWidth">
          <el-input v-model="updateObj.auhnor" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item
          label="出版社"
          prop="publishingHouse"
          :label-width="formLabelWidth"
        >
          <el-input
            v-model="updateObj.publishingHouse"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item
          label="原作名"
          prop="formerly"
          :label-width="formLabelWidth"
        >
          <el-input v-model="updateObj.formerly" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="出版年" prop="year" :label-width="formLabelWidth">
          <el-date-picker
            v-model="updateObj.year"
            type="date"
            placeholder="选择日期"
            style="width: 100%"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="页数" prop="pages" :label-width="formLabelWidth">
          <el-input v-model="updateObj.pages" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="定价" prop="price" :label-width="formLabelWidth">
          <el-input v-model="updateObj.price" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="ISBN" prop="isbn" :label-width="formLabelWidth">
          <el-input v-model="updateObj.isbn" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="update" :loading="updateLoading"
          >修 改</el-button
        >
      </div>
      <div class="cover">
        <img v-show="updateObj.cover" :src="updateObj.cover" alt="" />
        <el-upload
          action="zhanweifu"
          :auto-upload="false"
          :on-change="changeFile"
          :show-file-list="false"
        >
          <el-link
            v-show="!updateObj.cover"
            type="info"
            :underline="false"
            class="text"
            >上传封面</el-link
          >
        </el-upload>
        <i class="close" v-show="updateObj.cover" @click="updateObj.cover = ''"
          >X</i
        >
        <div
          class="uploadLoading"
          v-loading="uploadLoading"
          element-loading-text="正在上传封面"
          element-loading-spinner="el-icon-loading"
          element-loading-background="rgba(0, 0, 0, 0.7)"
        ></div>
      </div>
      <div class="img-help">
        <a href="https://docsmall.com/image-compress" target="_blank"
          >图片太大，快来压缩试试~</a
        >
      </div>
      <div class="context">
        <el-input
          type="textarea"
          :autosize="{ minRows: 10, maxRows: 10 }"
          placeholder="请输入内容详情"
          v-model="updateObj.detail"
        >
        </el-input>
      </div>
    </el-dialog>
    <!-- dialog框（写评论） -->
    <el-dialog
      style="width: 60%; margin: 14vh auto 0"
      title="写短评"
      :center="true"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
    >
      <el-input
        v-model="remark"
        type="textarea"
        :autosize="{ minRows: 3, maxRows: 6 }"
        placeholder="请说出您的看法..."
      ></el-input>
      <div style="text-align: right">
        <el-button style="margin-top: 20px" @click="remark = ''"
          >清空</el-button
        >
        <el-button
          type="primary"
          style="margin-top: 20px"
          @click="smt"
          :loading="smtLoading"
          >提交</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script>
import PercentageView from "../../components/PercentageView.vue";
import RemarkView from "@/components/RemarkView.vue";
import { getBookById, updateBook } from "@/api/book.js";
import {
  uploadFile,
  getWantOrSeeStatus,
  changeWantOrSeeStatus,
  getReviewsList,
  writeReviews,
  userRating,
  getRate,
} from "@/api/common.js";
import { isValidToken } from "@/utils/checkTokenValid";
import userInfo from "@/utils/userInfo.js";
export default {
  name: "DetailView",
  data() {
    return {
      writeRateValue: 0, // 评分的分数要乘以2
      want: 0, // wantOrSee判断 0:想看 1:已收藏
      see: 0, // wantOrSee判断 0:看过 1:已看过
      detailObj: {},
      updateObj: {},
      rateObj: {},
      starList: [],
      remarkList: [],
      // dialog框
      dialogVisible: false,
      dialogFormVisible: false,
      formLabelWidth: "120px",
      // 短评
      remark: "",
      // 加载
      smtLoading: false,
      uploadLoading: false,
      updateLoading: false,
      wantLoading: false,
      seeLoading: false,
      lastSubmittedTime: null, // 记录上次提交时间
      // 评分分页
      page: 1,
      pageSize: 10,
      total: 0,
      // 当前页数
      currentPage: 1,
      rulesUpdate: {
        title: [{ required: true, message: "请输入书名", trigger: "blur" }],
        auhnor: [{ required: true, message: "请输入作者", trigger: "blur" }],
        publishingHouse: [
          { required: true, message: "请输入出版社", trigger: "blur" },
        ],
        formerly: [
          { required: true, message: "请输入原作名", trigger: "blur" },
        ],
        year: [{ required: true, message: "请输入出版年", trigger: "blur" }],
        pages: [{ required: true, message: "请输入页数", trigger: "blur" }],
        price: [{ required: true, message: "请输入定价", trigger: "blur" }],
        isbn: [{ required: true, message: "请输入ISBN", trigger: "blur" }],
      },
    };
  },
  components: {
    PercentageView,
    RemarkView,
  },
  props: ["id"], // 接收父组件传过来的参数
  computed: {
    rateVal: {
      get() {
        return this.rateObj.avgRate / 2;
      },
      set() {},
    },
  },
  created() {
    this.getBookDetail();
    this.getRemarkList();
    this.getRateList();
    this.getWantOrSeeStatus();
  },
  methods: {
    // 写短评判断
    async writeRemark() {
      const flag = await isValidToken();
      if (!flag) {
        this.$router.push("/login");
        this.$message.error("请先登录！");
        return;
      }
      this.dialogVisible = true;
    },
    // 获取想看或看过状态
    // 初始化想看或看过的状态（仅限每个类型中的模块第一次进入时设置，其余均只用修改值即可）
    async getWantOrSeeStatus() {
      const user = userInfo.getUser();
      if (!user) return;
      const res = await getWantOrSeeStatus({
        type: "book",
        typeId: this.id,
        userId: user.userId,
      });
      this.want = res.data.wantStatus;
      this.see = res.data.seeStatus;
    },
    // 想看或看过
    async wantOrSeeChange(state) {
      if (state === "want") {
        try {
          this.wantLoading = true;
          const res = await changeWantOrSeeStatus({
            type: "book",
            typeId: this.id,
            wantStatus: this.want == 0 ? 1 : 0,
            seeStatus: this.see,
          });
          this.getWantOrSeeStatus();
        } finally {
          this.wantLoading = false;
        }
      } else if (state === "see") {
        try {
          this.seeLoading = true;
          const res = await changeWantOrSeeStatus({
            type: "book",
            typeId: this.id,
            wantStatus: this.want,
            seeStatus: this.see == 0 ? 1 : 0,
          });
          this.getWantOrSeeStatus();
        } finally {
          this.seeLoading = false;
        }
      }
    },
    // 提交评论
    async smt() {
      if (this.remark === "") {
        this.$message.warning("评论不能为空");
        return;
      }
      this.smtLoading = true;
      const res = await writeReviews({
        type: "book",
        typeId: this.id,
        content: this.remark,
      });
      this.smtLoading = false;
      this.remark = "";
      this.getRemarkList();
      this.dialogVisible = false;
    },
    // 评分
    async rateChange() {
      // 获取当前时间戳
      const currentTime = new Date().getTime();
      if (
        this.lastSubmittedTime &&
        currentTime - this.lastSubmittedTime < 3000
      ) {
        this.$notify({
          title: "操作过于频繁",
          type: "warning",
          duration: 1500,
        });
        return;
      }

      const res = await userRating({
        type: "book",
        typeId: this.id,
        rateVal: this.writeRateValue * 2,
      });
      if (res.msg === "success") {
        this.$notify({
          title: "评分成功",
          type: "success",
          duration: 2000,
        });
        this.getRateList();
        this.lastSubmittedTime = currentTime; // 更新上一次提交的时间
      }
    },
    // 获取书籍详情
    async getBookDetail() {
      const res = await getBookById(this.id);
      this.detailObj = Object.assign({}, res.data);
      this.updateObj = Object.assign({}, res.data);
    },
    // 获取评论列表
    async getRemarkList() {
      const res = await getReviewsList({
        type: "book",
        typeId: this.id,
        page: this.page,
        pageSize: this.pageSize,
      });
      this.remarkList = res.data.records;
      this.total = res.data.total;
      this.remarkList = this.remarkList.map((item) => {
        return {
          ...item,
          rate: item.rate / 2,
        };
      });
    },
    // 当前页发生改变时触发
    handleCurrentChange(val) {
      this.page = val;
      this.getRemarkList();
    },
    // 获取评分信息
    async getRateList() {
      const user = userInfo.getUser();
      const res = await getRate({
        type: "book",
        typeId: this.id,
        userId: user ? user.userId : 0,
      });
      this.rateObj = res.data;
      this.starList = res.data.rateList;
      // 在后端已经解决小数问题
      // this.starList = res.data.rateList.map((item) => {
      //   return {
      //     ...item,
      //     percentage: item.percentage.toFixed(2),
      //   };
      // });
      this.writeRateValue = res.data.userRate;
    },
    // 修改信息
    update() {
      this.$refs.updateForm.validate(async (v) => {
        if (v) {
          if (this.updateObj.cover == "") {
            this.$message.error("请上传封面");
            return;
          }
          if (this.updateObj.detail == "") {
            this.$message.error("请输入详情");
            return;
          }
          try {
            this.updateLoading = true;
            this.updateObj.id = this.id;
            const res = await updateBook(this.updateObj);
            this.dialogFormVisible = false;
            this.getBookDetail();
          } finally {
            this.updateLoading = false;
          }
        }
      });
    },
    // 选择文件，上传封面
    async changeFile(file) {
      // 判断格式是否正确
      const bool = this.verifyFormat(file);
      if (!bool) {
        return;
      }
      // 上传到服务器
      // console.log("上传到服务器,返回图片路径赋值给insertForm.cover");
      this.uploadLoading = true;
      let formData = new FormData();
      // 拿到存在file中的文件存放到formData中
      formData.append("file", file.raw);
      const res = await uploadFile(formData);
      this.uploadLoading = false;
      this.updateObj.cover = res.data;
    },
    // 上传封面前校验格式
    verifyFormat(file) {
      const isJPG =
        file.raw.type === "image/jpeg" || file.raw.type === "image/png";
      const isLt2M = file.raw.size / 1024 / 1024 < 2;
      if (!isJPG) {
        this.$message.error("上传头像图片只能是 jpg/jpeg/png 格式!");
        return false;
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
        return false;
      }
      return isJPG && isLt2M;
    },
    // 关闭对话框时重置数据
    closeFormDialog() {
      this.updateObj = Object.assign({}, this.detailObj);
      this.$refs.updateForm.resetFields();
      this.updateLoading = false;
      this.uploadLoading = false;
    },
  },
};
</script>

<style lang="less" scoped>
.detail {
  padding: 10px 40px;
  .detail-title {
    margin: 10px 0;
    font-size: 25px;
    font-weight: 700;
    span {
      color: #777;
    }
  }
  .detail-body {
    display: flex;
    justify-content: space-between;
    margin-bottom: 30px;
    .detail-body-img {
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 11%;
      height: 200px;
      .img {
        width: 100%;
        height: 100%;
      }
      span {
        margin-top: 6px;
        font-size: 12px;
        color: #aaa;
        cursor: pointer;
      }
    }
    .detail-body-info {
      border-right: 1px solid #ddd;
      width: 52%;
      display: flex;
      flex-direction: column;
      span {
        margin: 2px 0;
        font-size: 14px;
      }
    }
    .detail-body-rate {
      width: 14%;
      color: #888;
      div:first-child {
        margin-bottom: 6px;
      }
      .rate-data {
        width: 88%;
        display: flex;
        justify-content: space-between;
        align-items: center;
        .rate-data-num {
          font-size: 28px;
        }
        .rate-data-star {
          display: flex;
          flex-direction: column;
          align-items: center;
          margin-bottom: 10px;
          text-align: right;
          span {
            font-size: 12px;
            color: rgb(110, 151, 199);
          }
        }
      }
    }
    .detail-body-operate {
      width: 20%;
      padding-left: 16px;
      .operate-btn {
        margin-bottom: 10px;
      }
      .operate-rate {
        display: flex;
        align-items: center;
        margin-bottom: 10px;
      }
      span {
        font-size: 13px;
      }
    }
  }
  .detail-introduce {
    width: 68%;
    .detail-introduce-title {
      margin: 14px 0;
      color: rgb(12, 128, 122);
    }
    .detail-introduce-content {
      text-indent: 2em;
      line-height: 19px;
      font-size: 13px;
    }
  }
  .detail-remark {
    width: 68%;
    .remark-title {
      margin: 12px 0;
      color: rgb(12, 128, 122);
    }
  }
}
// 星级样式设置
/deep/.el-rate__icon {
  font-size: 18px;
  margin-right: -2px;
} // el-dialog样式
/deep/.el-dialog {
  width: 47%;
  position: relative;
  .cover {
    position: absolute;
    top: 12%;
    right: 14%;
    width: 20%;
    height: 28%;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
    img {
      width: 100%;
      height: 100%;
      // 当src为空时，设置透明度为0，使其不可见
      &[src=""],
      &:not([src]) {
        opacity: 0;
      }
    }
    .close {
      position: absolute;
      z-index: 9999;
      top: 0;
      right: 0;
      width: 20px;
      height: 20px;
      background-color: #fff;
      display: inline-block;
      text-align: center;
      line-height: 16px;
      font-style: normal;
      border: 2px solid;
      cursor: pointer;
      border-radius: 50%;
    }
    .text {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      z-index: 9999;
    }
    .uploadLoading {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
  }
  .img-help {
    position: absolute;
    right: 12.7%;
    top: 42%;
    a {
      text-decoration: none;
      color: #aaa;
      font-size: 13px;
    }
  }
  .context {
    position: absolute;
    bottom: 19.6%;
    right: 3%;
    width: 42%;
    margin: 0 auto;
    margin-top: 5%;
  }
}
.el-form {
  width: 50%;
}
/deep/.el-input__inner {
  width: 14vw;
}
.wantOrSee_f {
  background-color: rgb(83, 168, 255);
  color: #fff;
}
.wantOrSee_t {
  background-color: rgb(103, 194, 58);
  color: #fff;
}
</style>